﻿using System;
using System.Reflection;
using System.Runtime.Serialization;
using Pfz.Extensions;

namespace Pfz.Serialization.BinaryBuiltIn
{
	/// <summary>
	/// Serializer for EventInfo.
	/// </summary>
	public sealed class EventInfoSerializer:
		IItemSerializer
	{
		/// <summary>
		/// Gets the singleton instance.
		/// </summary>
		public static readonly EventInfoSerializer Instance = new EventInfoSerializer();

		private EventInfoSerializer()
		{
		}

		/// <summary>
		/// Serializes an EventInfo.
		/// </summary>
		public void Serialize(ConfigurableSerializerBase serializer, EventInfo item)
		{
			TypeSerializer.Instance.Serialize(serializer, item.ReflectedType);
			serializer.Stream.WriteString(item.Name);
		}

		/// <summary>
		/// Deserializes an EventInfo.
		/// </summary>
		public EventInfo Deserialize(ConfigurableSerializerBase deserializer)
		{
			Type type = TypeSerializer.Instance.Deserialize(deserializer);
			string name = deserializer.Stream.ReadString();

			var result = type.GetEvent(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (result == null)
				throw new SerializationException("Can't find property " + name + " on type " + type.FullName);

			return result;
		}

		private static readonly Type _forType = typeof(AppDomain).GetEvent("UnhandledException").GetType();
		Type IItemSerializer.ForType
		{
			get
			{
				return _forType;
			}
		}

		void IItemSerializer.Serialize(ConfigurableSerializerBase serializer, object item)
		{
			Serialize(serializer, (EventInfo)item);
		}

		object IItemSerializer.Deserialize(ConfigurableSerializerBase deserializer)
		{
			return Deserialize(deserializer);
		}
	}
}
